package com.xiaoshuidi.cloud.module.rooms.job.xxljob;

import cn.hutool.core.util.ObjectUtil;
import com.xiaoshuidi.cloud.framework.tenant.core.aop.TenantIgnore;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.BaiDuMapUtil;
import com.xiaoshuidi.cloud.module.rooms.pojo.Apartment;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomApartmentArea;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomArea;
import com.xiaoshuidi.cloud.module.rooms.repository.*;
import com.xiaoshuidi.cloud.module.rooms.service.MapService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class UpdateLonLatJob {

    private final ApartmentRepository apartmentRepository;
    private final RoomApartmentAreaRepository roomApartmentAreaRepository;
    private final RoomAreaRepository roomAreaRepository;
    private final BaiDuMapUtil baiDuMapUtil;
    private final MapService mapService;

    /**
     * 更新门店/小区经纬度为百度坐标系
     * 涉及表:
     * room_apartment   查经纬度
     * room_apartment_area 从room_area获取
     * room_area   查经纬度
     * room_hf_metro  合肥地铁经纬度
     * room_street_latlon 街道经纬度
     */
    @XxlJob("update-lon-lat")
    @TenantIgnore
    public void updateLonLat(){
        log.info("更新门店/小区经纬度为百度坐标系----开始");
        // 获取所有门店
        List<Apartment> apartmentList = apartmentRepository.list();
        List<Apartment> apartments = new ArrayList<>();

        try {
            for (int i = 0; i < apartmentList.size(); i++) {
                Apartment apartment = apartmentList.get(i);
                String fullAddress = apartment.getProvince() + apartment.getCity() + apartment.getDistrict() + apartment.getStreet() + apartment.getAddress();
                // 根据门店地址获取对应经纬度
                String lonLat = baiDuMapUtil.locationSearch(fullAddress,apartment.getCity());
                if(ObjectUtil.isEmpty(lonLat)){
                    continue;
                }
                String[] split = lonLat.split(",");
                String lon = split[0];
                String lat = split[1];
                apartment.setLongitude(lon);
                apartment.setLatitude(lat);
                apartments.add(apartment);
                // 每满一百条数据, 更新一次门店经纬度记录
                if(apartments.size() == 100){
                    apartmentRepository.updateBatchById(apartments);
                    apartments.clear();
                }
                Thread.sleep(50);
            }
            // 更新一次门店经纬度记录, 防止有数据未更新
            if(ObjectUtil.isNotEmpty(apartments)){
                apartmentRepository.updateBatchById(apartments);
                apartments.clear();
            }

            // 获取所有小区
            List<RoomArea> roomAreaList = roomAreaRepository.list();
            List<RoomArea> roomAreas = new ArrayList<>();
            for (int i = 0; i < roomAreaList.size(); i++) {
                RoomArea roomArea = roomAreaList.get(i);
                String province = ObjectUtil.isNotEmpty(roomArea.getProvince()) ? roomArea.getProvince() : "";
                String city = ObjectUtil.isNotEmpty(roomArea.getCity()) ? roomArea.getCity() : "";
                String district = ObjectUtil.isNotEmpty(roomArea.getDistrict()) ? roomArea.getDistrict() : "";
                String street = ObjectUtil.isNotEmpty(roomArea.getStreet()) ? roomArea.getStreet() : "";
                String name = ObjectUtil.isNotEmpty(roomArea.getName()) ? roomArea.getName() : "";
                String address = ObjectUtil.isNotEmpty(roomArea.getAddress()) ? roomArea.getAddress() : "";
                String fullAddress = province + city + district + street + name + address;
                // 根据门店地址获取对应经纬度
                String lonLat = baiDuMapUtil.locationSearch(fullAddress,city);
                if(ObjectUtil.isEmpty(lonLat)){
                    continue;
                }
                String[] split = lonLat.split(",");
                String lon = split[0];
                String lat = split[1];
                roomArea.setGeoLng(lon);
                roomArea.setGeoLat(lat);
                roomAreaList.get(i).setGeoLat(lat);
                roomAreaList.get(i).setGeoLng(lon);
                roomAreas.add(roomArea);
                // 每满一百条数据, 更新一次小区经纬度记录
                if(roomAreas.size() == 100){
                    roomAreaRepository.updateBatchById(roomAreas);
                    roomAreas.clear();
                }
                Thread.sleep(50);
            }

            if(ObjectUtil.isNotEmpty(roomAreas)){
                roomAreaRepository.updateBatchById(roomAreas);
                roomAreas.clear();
            }

            Map<Long, RoomArea> roomAreaMap = roomAreaList.stream().collect(Collectors.toMap(RoomArea::getId, o -> o));
            // 获取所有楼栋
            List<RoomApartmentArea> roomApartmentAreaList = roomApartmentAreaRepository.list();
            List<RoomApartmentArea> roomApartmentAreas = new ArrayList<>();
            for (int i = 0; i < roomApartmentAreaList.size(); i++) {
                RoomApartmentArea roomApartmentArea = roomApartmentAreaList.get(i);
                RoomArea roomArea = roomAreaMap.get(roomApartmentArea.getRoomAreaId());
                if(ObjectUtil.isEmpty(roomArea)){
                    continue;
                }
                // 更新楼栋经纬度信息, 和小区一致
                roomApartmentArea.setLongitude(roomArea.getGeoLng());
                roomApartmentArea.setLatitude(roomArea.getGeoLat());
                roomApartmentAreas.add(roomApartmentArea);
                if(roomApartmentAreas.size() == 100){
                    roomApartmentAreaRepository.updateBatchById(roomApartmentAreas);
                    roomApartmentAreas.clear();
                }
            }

            if(ObjectUtil.isNotEmpty(roomApartmentAreas)){
                roomApartmentAreaRepository.updateBatchById(roomApartmentAreas);
                roomApartmentAreas.clear();
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        log.info("更新门店/小区经纬度为百度坐标系----完成");
    }

    /**
     * 更新redis中的经纬度数据
     */
    @XxlJob("update-redis-lon-lat")
    @TenantIgnore
    public void updateRedisLonLat(){
        log.info("更新redis中的经纬度数据----开始");
        mapService.snycLatLonToRedis();
        log.info("更新redis中的经纬度数据----完成");
    }
}
